package com.li.aop.aspect;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.*;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

@Component
@Aspect // 切面类是需要用 @Aspect 注解进行标注的
@Order(2) //设置优先级
public class LogAspect {

    //定义通用的切点表达式
    @Pointcut("execution(* com.li.aop.service..*(..)))")
    public void pointcut() {}

    //前置通知
//    @Before("execution(* com.li.aop.service.UserService.*(..))")
//    @Before("execution(* com.li.aop.service.UserService.login(..))")
    @Before("pointcut()")
    public void beforeAddLog(JoinPoint joinPoint) {
        System.out.println("Log前置通知");
        //这个jointPonit，在Spring容器调用这个方法的时候自动传过来
        //我们可以直接用，用这个JointPoint joinPoint可以干啥？
        //getSignature：获取目标方法的签名
        Signature signature = joinPoint.getSignature();
        //通过方法的签名，可以获取到一个方法的具体信息
        System.out.println("目标方法的方法名：" + signature.getName());

    }

    //后置通知
    @AfterReturning("pointcut()")
    public void afterReturningAddLog() {
        System.out.println("Log后置通知");
    }

    //环绕通知
    @Around("pointcut()")
    public void aroundAddLog(ProceedingJoinPoint joinPoint) throws Throwable {
        //前面的代码
        System.out.println("Log前环绕");
        //执行目标
        joinPoint.proceed();
        //后面的代码
        System.out.println("Log后环绕");
    }

    //异常通知
    @AfterThrowing("pointcut()")
    public void afterThrowingLog() {
        System.out.println("Log异常通知");
    }

    //最终通知(finally语句块中的通知)
    @After("pointcut()")
    public void afterLog() {
        System.out.println("Log最终通知");
    }

}
